package han.gui;

import han.entity.ContactEntity;
import han.entity.FriendEntity;
import han.entity.GroupEntity;
import han.message.FriendManager;
import han.message.GroupManager;
import han.proof.FriendListProof;
import han.proof.GroupDetailInfo;
import han.util.PathTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;

/**
 * @author: Han
 * @date: 2018/7/24 14:14
 * @dscription: 群发窗体
 */
public class MainFrame extends JFrame {
    private static Logger logger = LoggerFactory.getLogger(MainFrame.class);
    private JPanel mainPane;
    private JTextArea editArea;
    private JButton sendBtn;
    private JButton friendListBtn;
    private JButton groupListBtn;
    private JTree listTree;
    private FriendListProof friendListProof;
    private GroupDetailInfo groupDetailInfo;
    /**
     * 实体标志位,0:朋友栏,1:群组栏
     */
    private int entityFlag = 0;

    public MainFrame() {

        friendListProof = FriendListProof.getInstance();

        groupDetailInfo = GroupDetailInfo.getInstance();

        addComponent();

        //默认设置显示好友列表
        setFriendTree();

        addFriendBtnListener();

        addGroupBtnListener();

        addSendBtnListener();

        addPopupMenuOnTree();

        setFragment();
    }

    /**
     * 添加各种组件
     */
    private void addComponent() {
        add(mainPane);
    }

    /**
     * 设置一些零碎的东西
     */
    private void setFragment() {

        setTitle("群发工具");
        setBounds(PopupBox.getPopupBoxRectangle(800, 600));
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
    }

    /**
     * 设置朋友树
     */
    private void setFriendTree() {

        entityFlag = 0;
        friendListBtn.setText("<html><u>好友</u></html>");
        groupListBtn.setText("群组");

        //分组存放分组信息
        List<FriendEntity> friendEntityList = friendListProof.getFriendList();
        Map<String, List<FriendEntity>> categoriesMap = new HashMap<>(10);
        for (FriendEntity friendEntity : friendEntityList) {
            String categoriesName = friendEntity.getCategoriesName();
            List<FriendEntity> tempList;
            if (categoriesMap.containsKey(categoriesName)) {
                tempList = categoriesMap.get(categoriesName);
            } else {
                tempList = new ArrayList<>();
            }
            tempList.add(friendEntity);
            categoriesMap.put(categoriesName, tempList);
        }

        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
        Set<String> categoriesSet = categoriesMap.keySet();
        //分组显示好友信息
        for (String categoriesName : categoriesSet) {
            DefaultMutableTreeNode tempCategoriesNode = new DefaultMutableTreeNode(categoriesName);
            List<FriendEntity> friendList = categoriesMap.get(categoriesName);
            for (FriendEntity friendEntity : friendList) {
                DefaultMutableTreeNode friendNode = new DefaultMutableTreeNode(friendEntity);
                tempCategoriesNode.add(friendNode);
            }
            rootNode.add(tempCategoriesNode);
        }

        TreeModel treeModel = new DefaultTreeModel(rootNode);
        listTree.setModel(treeModel);
    }

    /**
     * 设置群组树
     */
    private void setGroupTree() {

        entityFlag = 1;
        friendListBtn.setText("好友");
        groupListBtn.setText("<html><u>群组</u></html>");

        //根节点
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();

        Map<String, GroupEntity> entityMap = groupDetailInfo.getGroupMap();
        Collection<GroupEntity> groupEntityCollection = entityMap.values();
        for (GroupEntity entity : groupEntityCollection) {
            DefaultMutableTreeNode tempNode = new DefaultMutableTreeNode(entity);
            rootNode.add(tempNode);
        }

        TreeModel treeModel = new DefaultTreeModel(rootNode);
        listTree.setModel(treeModel);
    }

    /**
     * 添加发送按钮事件
     */
    private void addSendBtnListener() {
        sendBtn.addActionListener(e -> {
            //获取所有已选择的节点
            TreePath[] treePaths = listTree.getSelectionPaths();
            //如果为空,返回
            if (Objects.isNull(treePaths)) {
                JOptionPane.showMessageDialog(this, "请选择群发对象", "提示", JOptionPane.ERROR_MESSAGE);
                return;
            }
            //使用Set去重
            Set<ContactEntity> contactEntitySet = new HashSet<>();
            //遍历所有节点
            for (TreePath treePath : treePaths) {
                //获取目前节点
                DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) treePath.getLastPathComponent();
                //如果是叶子节点
                if (tempNode.isLeaf()) {
                    //获取节点的联系人对象
                    ContactEntity entity = (ContactEntity) tempNode.getUserObject();
                    contactEntitySet.add(entity);
                } else {
                    //获取分组名下一级的子节点枚举
                    Enumeration childrenEnum = tempNode.children();
                    //遍历所有子节点
                    while (childrenEnum.hasMoreElements()) {
                        //获取当前节点
                        DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) childrenEnum.nextElement();
                        //获取节点的联系人对象
                        ContactEntity entity = (ContactEntity) childNode.getUserObject();
                        contactEntitySet.add(entity);
                    }
                }
            }
            //写入提示
            StringBuilder tips = new StringBuilder("是否发送以上信息到给以下");
            if (entityFlag == 0) {
                tips.append("好友\n");
            } else {
                tips.append("群\n");
            }
            //遍历所有需要发送的联系人名称
            for (ContactEntity contactEntity : contactEntitySet) {
                tips.append(contactEntity.getName()).append("\n");
            }
            //询问是否向指定好友或者群组群发信息
            int choose = JOptionPane.showConfirmDialog(this, tips, "群发提示", JOptionPane.YES_NO_OPTION);
            if (choose == JOptionPane.YES_OPTION) {
                //确定发送
                sendMessage(contactEntitySet);
            }
        });
    }

    /**
     * 发送信息
     *
     * @param contactEntitySet 发送对象
     */
    private void sendMessage(Set<ContactEntity> contactEntitySet) {

        //获取将要发送的内容
        String content = editArea.getText();

        if (entityFlag == 0) {
            //向朋友群发消息
            for (ContactEntity entity : contactEntitySet) {
                //获取名称
                String nickname = entity.getName();
                //获取朋友uin
                long uin = entity.getUin();
                try {
                    //发送信息
                    FriendManager.sendToFriend(uin, content);
                    logger.info("好友:" + nickname + "发送成功");
                } catch (Exception e) {
                    logger.error("好友:" + nickname + "发送失败");
                    logger.info(e.toString());
                    StackTraceElement[] stackTraceElements = e.getStackTrace();
                    for (StackTraceElement stackTraceElement : stackTraceElements) {
                        logger.error(stackTraceElement.toString());
                    }
                } finally {
                    try {
                        //每100毫秒发送一条
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            //向群组群发消息
            for (ContactEntity entity : contactEntitySet) {
                //获取群组uin
                long uin = entity.getUin();
                //获取群名称
                String name = entity.getName();
                try {
                    //发送消息
                    GroupManager.sendToGroup(uin, content);
                    logger.info("群组:" + name + "发送成功");
                } catch (Exception e) {
                    logger.error("群组:" + name + "发送失败");
                    logger.info(e.toString());
                    StackTraceElement[] stackTraceElements = e.getStackTrace();
                    for (StackTraceElement stackTraceElement : stackTraceElements) {
                        logger.error(stackTraceElement.toString());
                    }
                } finally {
                    try {
                        //每100毫秒发送一条
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        //清空编辑框
        editArea.setText("");
    }

    /**
     * 添加好友按钮监听事件
     */
    private void addFriendBtnListener() {
        friendListBtn.addActionListener(e -> setFriendTree());
    }

    /**
     * 添加群组按钮监听事件
     */
    private void addGroupBtnListener() {
        groupListBtn.addActionListener(e -> setGroupTree());
    }

    /**
     * 添加清除树节点弹出框
     */
    private void addPopupMenuOnTree() {
        String path = PathTool.getPath();
        String imagePath = path + "\\\\image\\clear.png";
        JMenuItem clearItem = new JMenuItem("清空所选", new ImageIcon(imagePath));
        clearItem.addActionListener(e -> listTree.clearSelection());
        JPopupMenu popupMenu = new JPopupMenu();
        popupMenu.add(clearItem);
        listTree.add(popupMenu);
        listTree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3) {
                    popupMenu.show(listTree, e.getX(), e.getY());
                }
            }
        });
    }
}
